package com.nuoniu.sibanyun.service.finance.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.entity.erp.ErpAccount;
import com.nuoniu.sibanyun.entity.finance.VAccountingLedger;
import com.nuoniu.sibanyun.entity.finance.VAccountingVoucherDetail;
import com.nuoniu.sibanyun.entity.finance.VAssetsLiabilitiesFormula;
import com.nuoniu.sibanyun.entity.finance.VAssetsLiabilitiesMain;
import com.nuoniu.sibanyun.mapper.finance.VAssetsLiabilitiesMainMapper;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.finance.IVAccountingLedgerService;
import com.nuoniu.sibanyun.service.finance.IVAssetsLiabilitiesFormulaService;
import com.nuoniu.sibanyun.service.finance.IVAssetsLiabilitiesMainService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import com.nuoniu.sibanyun.utils.ExcelUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 资产负债表 服务实现类
 * </p>
 *
 * @author 小啊刚
 * @since 2021-05-26
 */
@Service
public class VAssetsLiabilitiesMainServiceImpl extends ServiceImpl<VAssetsLiabilitiesMainMapper, VAssetsLiabilitiesMain> implements IVAssetsLiabilitiesMainService {

    @Autowired
    private IErpAccountService accountService;
    @Autowired
    private IVAssetsLiabilitiesFormulaService formulaService;
    @Autowired
    private IVAccountingLedgerService ledgerService;
    @Autowired
    private HttpServletResponse response;

    @Override
    @Transactional
    public void saveAssetsLiabilities(List<VAssetsLiabilitiesMain> assetsLiabilities) {
        UserInfo userInfo = UserThreadLocal.get();
        ErpAccount account = accountService.getLastErpAccount();
        List<Long> alIds = new ArrayList<>();
        for(VAssetsLiabilitiesMain assetsLiabilitiesMain : assetsLiabilities) {
            if(assetsLiabilitiesMain.getId() == null) {
                assetsLiabilitiesMain.setAccountYear(account.getAccountYear());
                assetsLiabilitiesMain.setCompanyId(userInfo.getCompanyId());
                assetsLiabilitiesMain.setCompanyName(userInfo.getCompanyName());
            }

            if(assetsLiabilitiesMain.getId() != null) {
                alIds.add(assetsLiabilitiesMain.getId());
            }
        }

        //删除多余表
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("company_id", userInfo.getCompanyId());
        wrapper.eq("type", assetsLiabilities.get(0).getType());
        if(alIds != null && alIds.size() > 0) {
            wrapper.notIn("id", alIds);
        }

        this.remove(wrapper);

        //保存
        saveOrUpdateBatch(assetsLiabilities);
        //保存公式
        saveFormula(assetsLiabilities);
    }

    @Override
    public List<VAssetsLiabilitiesMain> getAssetsLiabilities(Integer accountPeriod, Integer type) {
        ErpAccount account = accountService.getLastErpAccount();
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("account_year", account.getAccountYear());
        wrapper.eq("company_id", userInfo.getCompanyId());
        wrapper.eq("type", type);
        wrapper.orderByAsc("line, columns");

        List<VAssetsLiabilitiesMain> assetsLiabilitiesMains = list(wrapper);
        if(accountPeriod != null) {
            for(VAssetsLiabilitiesMain assetsLiabilities : assetsLiabilitiesMains) { //遍历获取公式
                if(assetsLiabilities.getValueType() != null && assetsLiabilities.getValueType().equals(2)) {
                    BigDecimal balance = new BigDecimal(0.0);
                    List<VAssetsLiabilitiesFormula> assetsLiabilitiesFormulas = formulaService.getByAlId(assetsLiabilities.getId());
                    for(VAssetsLiabilitiesFormula formula : assetsLiabilitiesFormulas) {
                        BigDecimal value = null;
                        switch (accountPeriod) {
                            case 0: value = formula.getValueYear(); break;
                            case 1: value = formula.getValueJanuary(); break;
                            case 2: value = formula.getValueFebruary(); break;
                            case 3: value = formula.getValueMarch(); break;
                            case 4: value = formula.getValueApril(); break;
                            case 5: value = formula.getValueMay(); break;
                            case 6: value = formula.getValueJune(); break;
                            case 7: value = formula.getValueJuly(); break;
                            case 8: value = formula.getValueAugust(); break;
                            case 9: value = formula.getValueSeptember(); break;
                            case 10: value = formula.getValueOctober(); break;
                            case 11: value = formula.getValueNovember(); break;
                            case 12: value = formula.getValueDecember(); break;
                        }

                        if(value != null) {
                            if(formula.getOperator().equals(1)) { //判断运算符
                                balance = balance.add(value);
                            }else {
                                balance = balance.subtract(value);
                            }
                        }
                    }
                    assetsLiabilities.setValue(balance.toString());
                    assetsLiabilities.setAssetsLiabilitiesFormulas(assetsLiabilitiesFormulas);
                }
            }
        }
        return assetsLiabilitiesMains;
    }

    @Override
    public List<VAssetsLiabilitiesFormula> getFormulaList(Long alId) {
        return formulaService.getByAlId(alId);
    }

    @Override
    public List<VAccountingLedger> getAccountingLedger(String code) {
        return ledgerService.getAccountingLedger(code, 1);
    }

    @Override
    public void newCountFormula(List<VAccountingVoucherDetail> voucherDetails) {
        ErpAccount account = accountService.getLastErpAccount();
        UserInfo userInfo = UserThreadLocal.get();
        String accountingIds = "";
        for (int i = 0; i < voucherDetails.size(); i++) {
            accountingIds += voucherDetails.get(i).getAccountId();
            if(i + 1 < voucherDetails.size()) {
                accountingIds += ",";
            }
        }

        String ids = baseMapper.getIds(account.getAccountYear(), userInfo.getCompanyId());
        //获取公式列表
        List<VAssetsLiabilitiesFormula> formulaList = formulaService.getByAlIds(ids, accountingIds);
        formulaList.forEach(a -> ledgerService.countFormula(a, account.getAccountYear()));
        formulaService.saveOrUpdateBatch(formulaList);
    }

    @Override
    public void saveFormula(List<VAssetsLiabilitiesMain> assetsLiabilities) {
        ErpAccount account = accountService.getLastErpAccount();
        for(VAssetsLiabilitiesMain assetsLiabilitiesMain : assetsLiabilities) {
            if(assetsLiabilitiesMain.getId() == null) {
                continue;
                //save(assetsLiabilitiesMain);
            }

            //保存公式
            if(assetsLiabilitiesMain.getAssetsLiabilitiesFormulas() != null && assetsLiabilitiesMain.getAssetsLiabilitiesFormulas().size() > 0) {
                List<Long> detailIds = new ArrayList<>();
                assetsLiabilitiesMain.getAssetsLiabilitiesFormulas().forEach(a -> {
                    if(a.getId() != null) {
                        detailIds.add(a.getId());
                    }

                    //计算公式的值
                    ledgerService.countFormula(a, account.getAccountYear());
                    a.setAlId(assetsLiabilitiesMain.getId().intValue());
                });

                //删除多余公式
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("al_id", assetsLiabilitiesMain.getId());
                if(detailIds != null && detailIds.size() > 0) {
                    wrapper.notIn("id", detailIds);
                }

                formulaService.remove(wrapper);
                //保存公式
                formulaService.saveOrUpdateBatch(assetsLiabilitiesMain.getAssetsLiabilitiesFormulas());
            }else {
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("al_id", assetsLiabilitiesMain.getId());
                formulaService.remove(wrapper);
            }
        }
    }

    @Override
    public void exportData(Integer accountYear, Integer accountPeriod, Integer type) {
        Integer line = 1;
        HashMap<String, Object> data = new HashMap<>();
        List<HashMap<String, Object>> dataList = new ArrayList<>();
        String[] nameArr = {"资产负表", "损益表", "现金流量表"};
        String fileName = nameArr[type - 1] + ".xls";
        Object[] title = {"资产", "行次", "期末余额", "年初余额", "负责和所有者权益", "行次", "期末余额", "年初余额"};
        String[] inField = {"A", "B", "C", "D", "E", "F", "G", "H"};
        List<VAssetsLiabilitiesMain> liabilitiesMainList = getAssetsLiabilities(accountPeriod, type);
        for(VAssetsLiabilitiesMain main : liabilitiesMainList) {
            if(!line.equals(main.getLine())) {
                dataList.add(data);
                data = new HashMap<>();
                line = main.getLine();
            }

            data.put(main.getColumns(), main.getValue());
        }
        ExcelUtils.exportData(title, fileName, dataList, inField, response);
    }

}
